package com.qf.ability.gateway.sentinel.nacos;

import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.api.PropertyKeyConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;

import java.util.List;
import java.util.Properties;
import java.util.Set;

/**
 * description: 加载Nacos上的规则信息
 * author: Ken
 * 公众号：Java架构栈
 */
@Slf4j
public class NacosDatasourceLoader implements CommandLineRunner {

    @Autowired
    private NacosDatasourceConfig nacosDatasourceConfig;

    /**
     * 微服务启动后就会触发
     * @param args
     * @throws Exception
     */
    @Override
    public void run(String... args) throws Exception {
        log.debug("[gateway sentinel loader] 从nacos上获取Sentinel的相关规则数据 - {}", nacosDatasourceConfig);

        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, nacosDatasourceConfig.getServerAddr());
        properties.put(PropertyKeyConst.NAMESPACE, nacosDatasourceConfig.getNamespaces());

        //Nacos的数据源，从Nacos上读取流控规则列表
        NacosDataSource<Set<GatewayFlowRule>> nacosDataSource = new NacosDataSource<>(
                properties,
                nacosDatasourceConfig.getGroupId(),
                nacosDatasourceConfig.getFlowdataId(),
                json -> JSON.parseObject(json, new TypeReference<Set<GatewayFlowRule>>(){})
        );

        //加载当前服务的流控规则
        GatewayRuleManager.register2Property(nacosDataSource.getProperty());

        //从Nacos中读取熔断降级的规则列表
        NacosDataSource<List<DegradeRule>> nacosDataSourceDegrade = new NacosDataSource<>(
                properties,
                nacosDatasourceConfig.getGroupId(),
                nacosDatasourceConfig.getDegradedataId(),
                json -> JSON.parseObject(json, new TypeReference<List<DegradeRule>>(){})
        );

        //加载熔断降级的规则
        DegradeRuleManager.register2Property(nacosDataSourceDegrade.getProperty());
    }
}
